package com.alibaba.cirtus.ots.application.adapter.ability.facade.serviceV2.nyk;

import com.alibaba.cirtus.ots.application.adapter.ability.facade.serviceV2.sap.MnSapIf008V2ServiceImpl;
import com.alibaba.cirtus.ots.application.adapter.ability.model.enums.NykFailRecordEnum;
import com.alibaba.cirtus.ots.application.adapter.ability.utils.CodeUtil;
import com.alibaba.cirtus.ots.application.adapter.ability.utils.InfoUtil;
import com.alibaba.citrus.ots.common.annotation.ProcessInvoker;
import com.alibaba.citrus.ots.common.util.TimeUtil;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.model.dto.BaselineGetOrganizationByOutCodes2Request;
import com.epoch.app.bcorder.model.dto.BaselineGetOrganizationByOutCodes2Response;
import com.epoch.app.bcorder.model.dto.BaselineQueryScItemByPageRequest;
import com.epoch.app.bcorder.model.dto.OrganizationSDO;
import com.epoch.app.bcorder.model.dto.WarehouseInfo;
import com.epoch.app.bcorder.model.dto.WmsQueryWarehouseZoneListRequest;
import com.epoch.app.bcorder.model.dto.WmsQueryWarehouseZoneListResponse;
import com.epoch.app.bcorder.service.BaseDataService;
import com.epoch.app.bcorder.service.UnifiedInventoryService;
import com.epoch.app.crpricecenter.api.pricequery.service.PriceQueryService;
import com.epoch.app.crpricecenter.dto.request.DimensionPropertyInfoRequest;
import com.epoch.app.crpricecenter.dto.request.HumanInfoRequest;
import com.epoch.app.crpricecenter.dto.request.MaterialInfoRequest;
import com.epoch.app.crpricecenter.dto.request.PlaceInfoRequest;
import com.epoch.app.crpricecenter.dto.request.PriceQueryRequest;
import com.epoch.app.crpricecenter.dto.response.PriceQueryResponse;
import com.epoch.app.crpricecenter.model.enums.PriceTypeEnum;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorder.dto.AllocateApplyOrderLoadListRequest;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorder.model.AllocateApplyOrder;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorder.service.AllocateApplyOrderService;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorderdetail.model.AllocateApplyOrderDetail;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorderdetail.service.AllocateApplyOrderDetailService;
import com.epoch.app.crunifiedinventory.domain.allocateorder.dto.AllocateOrderLoadListRequest;
import com.epoch.app.crunifiedinventory.domain.allocateorder.dto.CreateAllocateOrderResponse;
import com.epoch.app.crunifiedinventory.domain.allocateorder.dto.DeleteAllocateOrderRequest;
import com.epoch.app.crunifiedinventory.domain.allocateorder.model.AllocateOrder;
import com.epoch.app.crunifiedinventory.domain.allocateorder.service.AllocateOrderService;
import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.dto.AllocateOrderDetailLoadListRequest;
import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.dto.CreateAllocateOrderDetailResponse;
import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.dto.DeleteAllocateOrderDetailRequest;
import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.model.AllocateOrderDetail;
import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.service.AllocateOrderDetailService;
import com.epoch.app.crunifiedinventory.model.dto.AllocateApplyOrderDetailListRequest;
import com.epoch.app.crunifiedinventory.model.enums.AllocateOrderStatus;
import com.epoch.app.crunifiedinventory.nykdatachecker.dto.StartProcessSaleOrdersRequest;
import com.epoch.app.crunifiedinventory.nykdatachecker.service.NykDataCheckerService;
import com.epoch.app.crunifiedinventory.ouinykfailrecord.model.OuiNykFailRecord;
import com.epoch.app.crunifiedinventory.ouinykfailrecord.service.OuiNykFailRecordService;
import com.epoch.app.crunifiedinventory.sdo.enums.AllocateOrderTypeEnum;
import com.epoch.app.otsapplicationadaptersdk.nyk.NykSaleOrder;
import com.epoch.app.otsapplicationadaptersdk.nyk.NykSaleOrderPageData;
import com.epoch.app.otsapplicationadaptersdk.nyk.NykSaleOrderResponse;
import com.epoch.app.otsapplicationadaptersdk.nyk.mnnyksaleorder.dto.DoHandlerRequest;
import com.epoch.app.otsapplicationadaptersdk.nyk.mnnyksaleorder.dto.DoHandlerResponse;
import com.epoch.app.otsapplicationadaptersdk.nyk.mnnyksaleorder.dto.GetAllNykSaleOrdersRequest;
import com.epoch.app.otsapplicationadaptersdk.nyk.mnnyksaleorder.dto.GetAllNykSaleOrdersResponse;
import com.epoch.app.otsapplicationadaptersdk.nyk.mnnyksaleorder.dto.GetNykSaleOrdersByApiAdaptorRequest;
import com.epoch.app.otsapplicationadaptersdk.nyk.mnnyksaleorder.dto.GetOneDayNykSaleOrdersRequest;
import com.epoch.app.otsapplicationadaptersdk.nyk.mnnyksaleorder.dto.GetOneDayNykSaleOrdersResponse;
import com.epoch.app.otsapplicationadaptersdk.nyk.mnnyksaleorder.service.MnNykSaleOrderService;
import com.epoch.app.otsapplicationadaptersdk.service.NykService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author zhoubc
 * @description: 牛要客总部销售调拨数据同步， 主子单处理模式
 * @date 2021/11/8 22:54
 */
@Component
public class MnNykSaleOrderV2ServiceImpl implements MnNykSaleOrderService {
    private final Log log = Log.getLogger(MnNykSaleOrderV2ServiceImpl.class);
    private static final int ITM_STATUS_DEL_VALUE = 0;
    private static final List<String> NUM_ZERO_TO_NINE = Lists.newArrayList("0","1","2","3","4","5","6","7","8","9");
    private static final String NYK_OPERATOR = "0";

    @Resource
    private NykService nykService;

    @Resource
    private AllocateOrderService allocateOrderService;

    @Resource
    private AllocateOrderDetailService allocateOrderDetailService;

    @Resource
    private UnifiedInventoryService unifiedInventoryService;

    @Resource
    private BaseDataService baseDataService;

    @Autowired
    private OuiNykFailRecordService ouiNykFailRecordService;

    @Autowired
    private PriceQueryService priceQueryService;

    @Resource(name = "nykSynTaskExecutor")
    private ThreadPoolTaskExecutor nykSynTaskExecutor;

    @Autowired
    private AllocateApplyOrderService allocateApplyOrderService;

    @Autowired
    private AllocateApplyOrderDetailService allocateApplyOrderDetailService;

    @Autowired
    private NykDataCheckerService nykDataCheckToolService;

    private static DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    private static DateTimeFormatter dfSecond = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    private void createErrorLog(String failureReason, NykSaleOrder record, DoHandlerRequest doHandlerRequest) {
        OuiNykFailRecord request = new OuiNykFailRecord();
        request.setFeatures(JSONObject.toJSONString(record));
        request.setFailureReason(failureReason);
        request.setQueryRequest(JSONObject.toJSONString(doHandlerRequest));
        request.setType(NykFailRecordEnum.SALE.getValue());
        request.setSubId(record.getVbapPosnr());
        request.setOrderId(record.getHeadId());
        ouiNykFailRecordService.create(request);
    }

    @Override
    public GetOneDayNykSaleOrdersResponse getOneDayNykSaleOrders(GetOneDayNykSaleOrdersRequest getOneDayNykSaleOrdersRequest){
        GetOneDayNykSaleOrdersResponse response = new GetOneDayNykSaleOrdersResponse();

        GetNykSaleOrdersByApiAdaptorRequest restNykSaleOrderDataRequest = new GetNykSaleOrdersByApiAdaptorRequest();

        if (StringUtils.isNotBlank(getOneDayNykSaleOrdersRequest.getStartDate())) {
            restNykSaleOrderDataRequest.setQueryDate(getOneDayNykSaleOrdersRequest.getStartDate());
        }
        String batchNo = getOneDayNykSaleOrdersRequest.getStartDate();
        final int size = 500;
        int current = 1;
        int total = 0;
        restNykSaleOrderDataRequest.setSize(String.valueOf(size));
        NykSaleOrderResponse restResponse;

        while (true){
            restNykSaleOrderDataRequest.setCurrent(String.valueOf(current));
            log.info("getOneDayNykSaleOrders:batchNo:{}, request", batchNo, JSONObject.toJSONString(restNykSaleOrderDataRequest));
            try {
                restResponse = getNykSaleOrdersByApiAdaptor(restNykSaleOrderDataRequest);
                log.info("getOneDayNykSaleOrders:batchNo:{}, response", batchNo, JSONObject.toJSONString(response));
            }catch (Exception e){
                log.error("getOneDayNykSaleOrders: error, batchNo:{}", batchNo);
                log.error("getOneDayNykSaleOrders: exception:", e);
                break;
            }
            if (Objects.isNull(restResponse) || Objects.isNull(restResponse.getData())) {
                log.error("getOneDayNykSaleOrders: batchNo:{}, Response_Is_Null", batchNo);
                break;
            }
            if (org.apache.commons.collections.CollectionUtils.isEmpty(restResponse.getData().getRecords()) ||
                    restResponse.getData().getTotal() == 0) {
                log.error("getOneDayNykSaleOrders: batchNo: {}, Response_Is_Empty", batchNo);
                break;
            }
            current++;
            total+=restResponse.getData().getRecords().size();
            //实际获取数量到少于size时，不需要再获取
            if (restResponse.getData().getRecords().size() < size) {
                log.error("getOneDayNykSaleOrders: batchNo: {}, Response_No_Remaining", batchNo);
                break;
            }

        }

        response.setCount(String.valueOf(total));
        return response;
    }

    @Override
    public GetAllNykSaleOrdersResponse getAllNykSaleOrders(GetAllNykSaleOrdersRequest getAllNykSaleOrdersRequest) {
        GetAllNykSaleOrdersResponse response = new GetAllNykSaleOrdersResponse();

        String endDate = getAllNykSaleOrdersRequest.getEndDate();
        if (StringUtils.isBlank(endDate)){
            endDate=String.valueOf(LocalDate.now());;
        }

        List<String> dateList = collectLocalDates(getAllNykSaleOrdersRequest.getStartDate(), endDate);

        DoHandlerRequest doHandlerRequest = new DoHandlerRequest();

        for (String oneDay : dateList) {
            doHandlerRequest.setQueryDate(oneDay);
            doHandlerRequest.setSize("500");
            DoHandlerResponse handlerResponse = doHandler(doHandlerRequest);
            response.setSuccessCount(String.valueOf(handlerResponse.getSuccessNum()));
        }
        return response;
    }

    /**
     * 收集起始时间到结束时间之间所有的时间并以字符串集合方式返回
     *
     * @param timeStart
     * @param timeEnd
     * @return
     */
    private static List<String> collectLocalDates(String timeStart, String timeEnd) {
        return collectLocalDates(LocalDate.parse(timeStart), LocalDate.parse(timeEnd));
    }

    /**
     * 收集起始时间到结束时间之间所有的时间并以字符串集合方式返回
     *
     * @param start
     * @param end
     * @return
     */
    private static List<String> collectLocalDates(LocalDate start, LocalDate end) {
        // 用起始时间作为流的源头，按照每次加一天的方式创建一个无限流
        return Stream.iterate(start, localDate -> localDate.plusDays(1))
                // 截断无限流，长度为起始时间和结束时间的差+1个
                .limit(ChronoUnit.DAYS.between(start, end) + 1)
                // 由于最后要的是字符串，所以map转换一下
                .map(LocalDate::toString)
                // 把流收集为List
                .collect(Collectors.toList());
    }

    @Override
    @ProcessInvoker
    public DoHandlerResponse doHandler(DoHandlerRequest doHandlerRequest) {
        log.info("同步牛要客销售预报单定时任务请求参数 : {}", JSON.toJSONString(doHandlerRequest));
        String T2DateStr = doHandlerRequest.getQueryDate() + " 00:00:00";
        LocalDateTime T2Date = LocalDateTime.parse(T2DateStr, dfSecond);
        int dayNum = T2Date.getDayOfMonth();
        log.info("同步牛要客销售预报单定时任务 请求参数阶段同步时间日期号 :" + dayNum);

        return handle(doHandlerRequest);
    }


    public DoHandlerResponse handle(DoHandlerRequest doHandlerRequest) {
        GetNykSaleOrdersByApiAdaptorRequest request = buildRequest(doHandlerRequest);
//        NykSaleOrderResponse response = nykService.restNykSaleOrderData(request);
        //切换请求为集成平台请求，为了记录请求日志
        NykSaleOrderResponse response = getNykSaleOrdersByApiAdaptor(request);
        log.info("restNykSaleOrderData, Response:{}", JSONObject.toJSONString(response));

        DoHandlerResponse doHandlerResponse = new DoHandlerResponse();
        // 检验 拉取数据是否成功
        String errorMessage = checkResponse(response);
        if (StringUtils.isNotBlank(errorMessage)) {
            doHandlerResponse.setSuccess(false);
            doHandlerResponse.setMessage(errorMessage);
            return doHandlerResponse;
        }
        List<String> successList = Lists.newArrayList();
        List<String> failList = Lists.newArrayList();
        Integer successNum = 0;
        Integer failNum = 0;

        //todo 魔法值增加注释
        BaselineGetOrganizationByOutCodes2Request organizationRequest =
                BaselineGetOrganizationByOutCodes2Request.builder().outCodes(Arrays.asList("6140")).status(1).build();
        BaselineGetOrganizationByOutCodes2Response baselineGetOrganizationByOutCodes2Response = baseDataService.baselineGetOrganizationByOutCodes2(organizationRequest);
        if (Objects.isNull(baselineGetOrganizationByOutCodes2Response) ||
                CollectionUtils.isEmpty(baselineGetOrganizationByOutCodes2Response.getResult())) {
            doHandlerResponse.setSuccess(false);
            doHandlerResponse.setMessage(errorMessage);
            return doHandlerResponse;
        }

        //2022.03.15 提报组织id为分子公司层级
        OrganizationSDO organizationSDO = baselineGetOrganizationByOutCodes2Response.getResult().get(0);
        String applyOrgId = organizationSDO.getId();
        if (Objects.equals(organizationSDO.getType(), 104)) {
            applyOrgId = organizationSDO.getParentId();
        }
//        String applyOrgId = baselineGetOrganizationByOutCodes2Response.getResult().get(0).getId();
        String batchNo= nykDataCheckToolService.generateBatchNo().getBatchNo();
        //第一次请求只是为了获取数据条数，下面才是真正的获取并处理数据，可以优化下少一次请求
        for (int i = 1; i <= response.getData().getPages(); i++) {
            request.setCurrent(String.valueOf(i));
//            NykSaleOrderResponse pageResponse = nykService.restNykSaleOrderData(request);
            NykSaleOrderResponse pageResponse = getNykSaleOrdersByApiAdaptor(request);
            log.info("getNykSaleOrdersByApiAdaptor, response:{}", JSONObject.toJSONString(pageResponse));
            saveProcessLogToCheckTool(batchNo, pageResponse, request.getQueryDate());

            List<NykSaleOrder> records = pageResponse.getData().getRecords();
            if (CollectionUtils.isEmpty(records)) {
                log.error("getNykSaleOrdersByApiAdaptor error， req:{}", JSON.toJSONString(pageResponse));
                continue;
            }
            Map<String, Object> map = syncCurrentPage(records, applyOrgId, successList, failList, doHandlerRequest);
            successNum = successNum + Integer.valueOf(map.get("successNum") + "");
            failNum = failNum + Integer.valueOf(map.get("failNum") + "");
        }

        doHandlerResponse.setSuccess(true);
        doHandlerResponse.setMessage("同步完成");
        doHandlerResponse.setResult(response);
        doHandlerResponse.setSuccessNum(successNum);
        doHandlerResponse.setFailNum(failNum);
        doHandlerResponse.setSuccessList(successList);
        doHandlerResponse.setFailList(failList);
        return doHandlerResponse;
    }

    /**
     * 保存业务处理日志，用于数据核对
     * @param batchNo
     * @param tmpResp
     */
    private void saveProcessLogToCheckTool(String batchNo, NykSaleOrderResponse tmpResp, String queryDate) {
        StartProcessSaleOrdersRequest logRequest = new StartProcessSaleOrdersRequest();
        logRequest.setBatchNo(batchNo);
        logRequest.setResponseJson(JSONObject.toJSONString(tmpResp));
        logRequest.setCount(tmpResp.getData().getRecords().size());
        logRequest.setTime(DateTime.now().toDate());
        logRequest.setQueryDate(queryDate);

        nykDataCheckToolService.startProcessSaleOrders(logRequest);
    }

    /**
     *
     * 组装 拉取牛要客调拨单 请求参数
     *
     * @param doHandlerRequest
     * @return
     */
    private GetNykSaleOrdersByApiAdaptorRequest buildRequest(DoHandlerRequest doHandlerRequest) {
        GetNykSaleOrdersByApiAdaptorRequest restNykSaleOrderDataRequest = new GetNykSaleOrdersByApiAdaptorRequest();
        restNykSaleOrderDataRequest.setCurrent(doHandlerRequest.getCurrent());
        restNykSaleOrderDataRequest.setSize(doHandlerRequest.getSize());
        if (StringUtils.isNotBlank(doHandlerRequest.getQueryDate())) {
            restNykSaleOrderDataRequest.setQueryDate(doHandlerRequest.getQueryDate());
        }
        return restNykSaleOrderDataRequest;
    }

    /**
     * 检验 拉取数据是否成功
     *
     * @param response
     * @return
     */
    private String checkResponse(NykSaleOrderResponse response) {
        if (Objects.isNull(response)) {
            return "没有查到同步数据";
        }
        if (response.getSuccess() == null) {
            return "查询失败,message：" + response.getMsg();
        }
        if (!response.getSuccess()) {
            return "查询失败,message：" + response.getMsg();
        }

        NykSaleOrderPageData data = response.getData();
        if (Objects.isNull(data) || CollectionUtils.isEmpty(data.getRecords())) {
            return "查询失败,message：" + response.getMsg();
        }
        return null;
    }

    private Map<String, Object> syncCurrentPage(List<NykSaleOrder> records, String applyOrgId,
                                                List<String> successList,
                                                List<String> failList,
                                                DoHandlerRequest doHandlerRequest) {
        AtomicReference<Integer> successNum = new AtomicReference<>(0);
        AtomicReference<Integer> failNum = new AtomicReference<>(0);

        // 按照主单分组
        Map<String, List<NykSaleOrder>> mainGroup = Optional.ofNullable(records).orElse(Lists.newArrayList()).stream().collect(Collectors.groupingBy(NykSaleOrder::getHeadId));
        List<CompletableFuture<String>> futures = Lists.newArrayList();
        for (Map.Entry<String, List<NykSaleOrder>> entry : mainGroup.entrySet()) {
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
                try {
                    dealMainOrder(applyOrgId, successList, failList, doHandlerRequest, successNum, failNum, entry);
                    return entry.getKey();
                } catch (Exception e) {
                    log.error(e, "同步牛要客销售主单数据失败, headkey: {}", entry.getKey());
                }
                return entry.getKey();
            }, nykSynTaskExecutor);

            futures.add(future);
        }

        for (CompletableFuture<String> future : futures) {
            try {
                String record = future.get();
                log.info("NykSaleOrder create sync success headerKey = {}", record);
            } catch (Exception e) {
                log.error(e, "NykSaleOrder create sync error");
            }
        }

        Map<String, Object> map = new HashMap<String, Object>() {{
            put("successNum", successNum.get());
            put("failNum", failNum.get());
            put("successList", JSONObject.toJSONString(successList));
            put("failList", JSONObject.toJSONString(failList));
        }};
        return map;
    }

    private void dealMainOrder(String applyOrgId, List<String> successList, List<String> failList, DoHandlerRequest doHandlerRequest, AtomicReference<Integer> successNum, AtomicReference<Integer> failNum, Map.Entry<String, List<NykSaleOrder>> entry) {
        // 处理一个主单
        AllocateOrder mainAllocateOrder = null;

        String outAllocateOrderId = entry.getKey();
        List<NykSaleOrder> subRecords = Optional.ofNullable(entry.getValue()).orElse(Lists.newArrayList());


        // 判断调拨单是否已存在
        AllocateOrderLoadListRequest allocateOrderLoadListRequest = new AllocateOrderLoadListRequest();
        allocateOrderLoadListRequest.setOutAllocateOrderId(outAllocateOrderId);
        Result<List<AllocateOrder>> loadAllocateOrderList = allocateOrderService.loadAllocateOrderList(allocateOrderLoadListRequest);
        if (loadAllocateOrderList != null && CollectionUtils.isNotEmpty(loadAllocateOrderList.getResult()) && loadAllocateOrderList.getResult().get(0) != null) {
            mainAllocateOrder = loadAllocateOrderList.getResult().get(0);
            mainAllocateOrder = deleteAllocateOrder(mainAllocateOrder, subRecords);
        }

        for (NykSaleOrder nykSaleOrder : subRecords) {
            String failListIdFlag = nykSaleOrder.getId();
            try {
                //2022.3.30 增加删除逻辑
                // 报文中，对应销售订单的的itmStatus字段为0，那么订单共享平台会根据这个销售订单的编号，把已经存储的销售订单删除掉。
                // 由于前面已经删除，因此这里判断是否需要删除，如果删除则不需要进行新建
                Boolean needDel = saleOrderNeedToDelete(nykSaleOrder);
                if (needDel) {
                    log.info("MnNykSaleOrderServiceImpl#dealMainOrde#needDel: id: {}, itmStatus: {}",
                            nykSaleOrder.getId(), nykSaleOrder.getItmStatus());
                    continue;
                }

                // 检验必填字段
                String check = check(nykSaleOrder);
                if (StringUtils.isNotBlank(check)) {
                    log.error("同步牛要客销售单数据失败，缺少参数 :{}， request: {}", check, JSONObject.toJSONString(nykSaleOrder));
                    failNum.getAndSet(failNum.get() + 1);
                    failList.add(failListIdFlag);
                    createErrorLog("同步牛要客销售单数据失败，缺少参数 " + check, nykSaleOrder, doHandlerRequest);
                    continue;
                }

                String code = CodeUtil.getCode(AllocateOrderTypeEnum.HEADQUARTER_SALES.getType());
                Boolean addFlag = false;
                // 如果 调拨单主单不存在 则新增调拨单主单  (主单存在 则删除本地数据，即以牛要客数据为准) CollectionUtils.isEmpty(loadAllocateOrderList.getResult())
                if (mainAllocateOrder == null || mainAllocateOrder.getId() == null) {
                    // 调拨单 新增
                    mainAllocateOrder = new AllocateOrder();

                    // 本系统字段意思 牛要客字段意思
                    // 外部单号     主单id
                    mainAllocateOrder.setOutAllocateOrderId(nykSaleOrder.getHeadId());

                    // 提报组织     默认6140对应组织
                    mainAllocateOrder.setApplyOrgId(applyOrgId);
                    // 调拨类型     默认总部销售调拨
                    mainAllocateOrder.setType(AllocateOrderTypeEnum.HEADQUARTER_SALES.getType());
                    // 产品组      常温11
                    mainAllocateOrder.setProductGroup("11");
                    // 单据状态     默认已收货
                    mainAllocateOrder.setStatus(AllocateOrderStatus.Received.getValue());
                    // 是否直发客户   默认否
                    mainAllocateOrder.setIsDTC(false);
                    // 是否退单     默认否
                    mainAllocateOrder.setReturnOrder(false);

                    // 查询收货仓 入参
                    // 收货工厂代码
                    String vbapLgort = "2028";
                    // 库存地点
                    String whseCode = nykSaleOrder.getVbapLgort();
                    // 查询收货仓
                    WmsQueryWarehouseZoneListRequest zoneListRequest = new WmsQueryWarehouseZoneListRequest();
                    // 默认根据 VbapLgort + 工厂编码2028
                    zoneListRequest.setWarehouseCode(whseCode);
                    zoneListRequest.setSapFactoryCode(vbapLgort);
                    WmsQueryWarehouseZoneListResponse receiveResponse = unifiedInventoryService.wmsQueryWarehouseZoneList(zoneListRequest);
                    if (ObjectUtils.isEmpty(receiveResponse) || (!ObjectUtils.isEmpty(receiveResponse) && CollectionUtils.isEmpty(receiveResponse.getResult()))) {
                        // 找不到 再根据 VbapLgort + 3650
                        zoneListRequest.setSapFactoryCode("3650");
                        receiveResponse = unifiedInventoryService.wmsQueryWarehouseZoneList(zoneListRequest);
                        if (ObjectUtils.isEmpty(receiveResponse) || (!ObjectUtils.isEmpty(receiveResponse) && CollectionUtils.isEmpty(receiveResponse.getResult()))) {
                            log.error("同步牛要客销售单数据失败，查询收货仓库不存在 request:{}", JSONObject.toJSONString(nykSaleOrder));
                            failNum.getAndSet(failNum.get() + 1);
                            failList.add(failListIdFlag);
                            createErrorLog("同步牛要客销售单数据失败，查询收货仓库不存在, sap工厂编码 = "
                                    + vbapLgort + " | 仓库编码 = " + whseCode, nykSaleOrder, doHandlerRequest);
                            continue;
                        }
                    }
                    String receiveAreaId = MnSapIf008V2ServiceImpl.getAreaId(receiveResponse);
                    String receiveWarehouseId = MnSapIf008V2ServiceImpl.getWarehouseId(receiveResponse);
                    // 收货仓
                    mainAllocateOrder.setReceiveWarehouseId(receiveWarehouseId);
                    // 收货仓-库区
                    mainAllocateOrder.setReceiveAreaId(receiveAreaId);
                    // 收货组织
                    mainAllocateOrder.setReceiveOrgId(getSaleOrgId(receiveResponse));

                    // 查询发货仓 入参
                    // 发货工厂代码
                    String deliveryCode = nykSaleOrder.getVbapWerks();
                    WmsQueryWarehouseZoneListRequest zoneListRequest1 = new WmsQueryWarehouseZoneListRequest();
                    // 默认 VbapWerks + DEFAULT 找
                    zoneListRequest1.setSapFactoryCode(deliveryCode);
                    zoneListRequest1.setWarehouseCode("DEFAULT");
                    WmsQueryWarehouseZoneListResponse deliveryResponse = unifiedInventoryService.wmsQueryWarehouseZoneList(zoneListRequest1);
                    if (ObjectUtils.isEmpty(deliveryResponse) || (!ObjectUtils.isEmpty(deliveryResponse) && CollectionUtils.isEmpty(deliveryResponse.getResult()))) {
                        // 找不到再根据 VbapWerks + VbapLgort 去找
                        zoneListRequest1.setWarehouseCode(nykSaleOrder.getVbapLgort());
                        deliveryResponse = unifiedInventoryService.wmsQueryWarehouseZoneList(zoneListRequest1);
                        if (ObjectUtils.isEmpty(deliveryResponse) || (!ObjectUtils.isEmpty(deliveryResponse) && CollectionUtils.isEmpty(deliveryResponse.getResult()))) {
                            log.error("同步牛要客销售单数据失败，查询发货仓库不存在 request:{}", JSONObject.toJSONString(nykSaleOrder));
                            failNum.getAndSet(failNum.get() + 1);
                            failList.add(failListIdFlag);
                            createErrorLog("同步牛要客销售单数据失败，查询发货仓库不存在 ， " +
                                    "sap工厂编码 = " + deliveryCode + "| 仓库编码 = " + nykSaleOrder.getVbapLgort(), nykSaleOrder, doHandlerRequest);
                            continue;
                        }
                    }
                    String deliveryAreaId = MnSapIf008V2ServiceImpl.getAreaId(deliveryResponse);
                    String deliveryWarehouseId = MnSapIf008V2ServiceImpl.getWarehouseId(deliveryResponse);
                    // 发货仓
                    mainAllocateOrder.setShipWarehouseId(deliveryWarehouseId);
                    // 发货仓-库区
                    mainAllocateOrder.setShipAreaId(deliveryAreaId);
                    // 发货组织
                    mainAllocateOrder.setShipOrgId(getSaleOrgId(deliveryResponse));

                    // 装运方式 默认01 汽运配送
                    mainAllocateOrder.setShipMethod(1);

                    // feature放来源
                    Map<String, String> map = new HashMap<String, String>() {{
                        put("source", "nyk");
                    }};
                    mainAllocateOrder.setFeatures(JSONObject.toJSONString(map));


                    mainAllocateOrder.setCode(code);
                    // 备注
                    mainAllocateOrder.setRemark(nykSaleOrder.getPreorderNo());

                    mainAllocateOrder.setGmt_create(TimeUtil.parseTime(nykSaleOrder.getCreatedTime()));
                    mainAllocateOrder.setCreator(NYK_OPERATOR);
                    mainAllocateOrder.setUpdater(NYK_OPERATOR);
                    log.info("MnNykSaleOrderServiceImpl, createAllocateOrder:{}", JSONObject.toJSONString(mainAllocateOrder));
                    CreateAllocateOrderResponse createOrderResponse = allocateOrderService.createAllocateOrder(mainAllocateOrder);
                    if (Objects.isNull(createOrderResponse) || Objects.isNull(createOrderResponse.getLastInsertId())) {
                        log.error("MnNykSaleOrderServiceImpl, create fail = {} , mainAllocateOrder {}", createOrderResponse, mainAllocateOrder);
                        log.error("MnNykSaleOrderServiceImpl, syncCurrentPage_fail");
                        createErrorLog("主单保存失败", nykSaleOrder, doHandlerRequest);
                        continue;
                    }

                    mainAllocateOrder.setId(createOrderResponse.getLastInsertId());
                }

                if (mainAllocateOrder == null || mainAllocateOrder.getId() == null) {
                    log.error("主单创建失败, {}", JSON.toJSONString(mainAllocateOrder));
                    createErrorLog("主单创建失败", nykSaleOrder, doHandlerRequest);
                    continue;
                }

                // 查询子单
                AllocateOrderDetail subOrder = null;
                AllocateOrderDetailLoadListRequest r = new AllocateOrderDetailLoadListRequest();
                r.setAllocateOrderId(mainAllocateOrder.getId());
                r.setOutAllocateOrderLineId(nykSaleOrder.getVbapPosnr());
                Result<List<AllocateOrderDetail>> loadAllocateOrderDetailList = allocateOrderDetailService.loadAllocateOrderDetailList(r);
                log.info("MnNykSaleOrderServiceImpl, query result:{}", JSONObject.toJSONString(loadAllocateOrderDetailList));
                if (loadAllocateOrderDetailList != null && CollectionUtils.isNotEmpty(loadAllocateOrderDetailList.getResult()) && loadAllocateOrderDetailList.getResult().get(0) != null) {
                    subOrder = loadAllocateOrderDetailList.getResult().get(0);
                }

                if (subOrder != null) {
                    createErrorLog("子单已存在", nykSaleOrder, doHandlerRequest);
                    continue;
                }

                // 如果 主单存在 且 调拨单明细不存在 则新增 调拨单明细
                if (subOrder == null) {
                    // 调拨单明细 新增
                    AllocateOrderDetail allocateOrderDetail = new AllocateOrderDetail();

                    // 外部行号     子单id
                    //20220107 修改为VbapPosnr
                    allocateOrderDetail.setOutAllocateOrderLineId(nykSaleOrder.getVbapPosnr());
                    //确认数量
                    //20220107 增加
                    allocateOrderDetail.setConfirmQuantity(nykSaleOrder.getVbepBmeng() + "");
                    // 调拨单id
                    allocateOrderDetail.setAllocateOrderId(mainAllocateOrder.getId());
                    // 调拨类型     默认总部销售单
                    allocateOrderDetail.setType(AllocateOrderTypeEnum.HEADQUARTER_SALES.getType());
                    // 行状态     已收货
                    allocateOrderDetail.setStatus(AllocateOrderStatus.Received.getValue());
                    // 货品编码    物料代码
                    allocateOrderDetail.setScItemCode(InfoUtil.deleteZeroPrefix(nykSaleOrder.getVbapMatnr()));
                    //期望发货
                    SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    allocateOrderDetail.setExpectedProduceDate(StringUtils.isBlank(nykSaleOrder.getVbapZfscrq()) ? null :
                            simpleDate.parse(parseDate(nykSaleOrder.getVbapZfscrq())));
                    // 货品id
                    String scItemId = InfoUtil.getScItemIdByOutCode(nykSaleOrder.getVbapMatnr());
                    allocateOrderDetail.setScItemId(scItemId);
                    // 货品名称 自动带出
                    allocateOrderDetail.setScItemName(getItNameByOutCode(allocateOrderDetail.getScItemCode()));
                    // 数量       销售订单数量
                    allocateOrderDetail.setQuantity(ObjectUtils.isEmpty(nykSaleOrder.getVbapKwmeng()) ? null : nykSaleOrder.getVbapKwmeng().toString());
                    // 单位
                    allocateOrderDetail.setUnit(getUnitByOutCode(allocateOrderDetail.getScItemCode()));
//                    // 单价 金额/销售订单数量
//                    if (StringUtils.isNotBlank(nykSaleOrder.getKomvKwert()) && nykSaleOrder.getVbapKwmeng() != null) {
//                        BigDecimal divide = new BigDecimal(nykSaleOrder.getKomvKwert()).divide(new BigDecimal(nykSaleOrder.getVbapKwmeng()));
//                        allocateOrderDetail.setPrice(divide.toString());
//                    }
                    // 折后金额
                    allocateOrderDetail.setDiscountAmount(nykSaleOrder.getKomvKwert());
                    allocateOrderDetail.setSubTotalAmount(nykSaleOrder.getKomvKwert());
                    // 期望生产日期   需求者/请求者姓名(生产日期）
                    //                allocateOrderDetail.setExpectedProduceDate(TimeUtil.parseSimpleDateFormat(nykSaleOrder.getCrtName()));
                    // 行备注
                    allocateOrderDetail.setRemarks(nykSaleOrder.getVbapZ013());
                    // 创建时间（行） 创建时间
                    allocateOrderDetail.setGmt_create(TimeUtil.parseTime(nykSaleOrder.getCreatedTime()));
                    allocateOrderDetail.setCreator(NYK_OPERATOR);
                    allocateOrderDetail.setUpdater(NYK_OPERATOR);
                    nykSaleOrder.setId(null);
                    allocateOrderDetail.setFeatures(JSONObject.toJSONString(nykSaleOrder));
                    allocateOrderDetail.setAllocateOrderCode(mainAllocateOrder.getCode());

                    // 获取到岸价
                    Long price = getNykSaleOrderPrice(nykSaleOrder, allocateOrderDetail, doHandlerRequest);
                    if (price == null) {
                        continue;
                    }

                    allocateOrderDetail.setPrice(new BigDecimal(price).divide(new BigDecimal(100)).setScale(2).toString());
                    long amount = price * Long.valueOf(allocateOrderDetail.getQuantity());
                    allocateOrderDetail.setSubTotalAmount(new BigDecimal(amount).divide(new BigDecimal(100)).setScale(2).toString());
                    log.info("MnNykSaleOrderServiceImpl, createAllocateOrder:{}", JSONObject.toJSONString(mainAllocateOrder));
                    CreateAllocateOrderDetailResponse detailResponse = allocateOrderDetailService.createAllocateOrderDetail(allocateOrderDetail);

                    if (Objects.isNull(detailResponse) || StringUtils.isBlank(detailResponse.getLastInsertId())) {
                        log.error("MnNykSaleOrderServiceImpl, create fail = allocateOrderDetail {} , detailResponse {}", allocateOrderDetail, detailResponse);
                        log.error("MnNykSaleOrderServiceImpl, syncCurrentPage_fail");
                        createErrorLog("子单保存失败", nykSaleOrder, doHandlerRequest);
                    }
                    addFlag = true;

                }
                log.info("MnNykSaleOrderServiceImpl, request: {}", JSONObject.toJSONString(nykSaleOrder));
                if (addFlag) {
                    successList.add(failListIdFlag);
                    successNum.getAndSet(successNum.get() + 1);
                }
            } catch (Exception e) {
                log.error(e, "同步牛要客销售单数据失败, request: {}", JSONObject.toJSONString(nykSaleOrder));
                failNum.getAndSet(failNum.get() + 1);
                failList.add(failListIdFlag);
                createErrorLog("系统异常", nykSaleOrder, doHandlerRequest);
            }
        }
    }

    /**
     * 判断是否需要删除销售订单
     *
     * @param nykSaleOrder
     * @return
     */
    private Boolean saleOrderNeedToDelete(NykSaleOrder nykSaleOrder) {
        if (Objects.isNull(nykSaleOrder) || Objects.isNull(nykSaleOrder.getItmStatus())) {
            return false;
        }

        return nykSaleOrder.getItmStatus().equals(ITM_STATUS_DEL_VALUE);
    }

    public static void main(String[] args) {

        String s = "";
        deleteZeroPrefix(s);
        StringBuilder newStr= new StringBuilder();
        List<String> numZeroToNine=Lists.newArrayList("0","1","2","3","4","5","6","7","8","9");
        char[] chars = s.toCharArray();
        for (int i = 0; i < s.length(); i++) {
            if (numZeroToNine.contains(String.valueOf(chars[i]))) {
                newStr.append(chars[i]);
            }
        }


        System.out.println(newStr);
        System.out.println(s.replace(" ","")+"--");

    }

    private String trimForSpecString(String str){
        if (StringUtils.isBlank(str)){
            return "";
        }
        StringBuilder newStr= new StringBuilder();
        char[] chars = str.toCharArray();
        for (int i = 0; i < str.length(); i++) {
            if (NUM_ZERO_TO_NINE.contains(String.valueOf(chars[i]))) {
                newStr.append(chars[i]);
            }
        }
        return newStr.toString();
    }
    /**
     * 组织：固定6000，
     * 物料：货品的outer_id
     * 货品组：固定11；
     * 工厂：发货仓的工厂CODE；
     * 客户：关联的预报单上的客户编码；
     * 分销渠道：固定20；
     *
     * @param nykSaleOrder
     * @param doHandlerRequest
     * @return
     */
    private Long getNykSaleOrderPrice(NykSaleOrder nykSaleOrder, AllocateOrderDetail allocateOrderDetail, DoHandlerRequest doHandlerRequest) {

        Long price = null;
        PriceQueryRequest priceQueryReq = buildPriceRequest(nykSaleOrder, allocateOrderDetail, doHandlerRequest);
        Result<PriceQueryResponse> priceQueryRep = priceQueryService.batchQueryPriceExpand(priceQueryReq);
        if (priceQueryRep != null && priceQueryRep.getResult() != null && CollectionUtils.isNotEmpty(priceQueryRep.getResult().getItemPriceResponseList())) {
            price = priceQueryRep.getResult().getItemPriceResponseList().get(0).getMoneyAmout();
        }

        if (price == null || price < 0) {
            log.error("查询价格失败, REP:{}, REQ:{}", JSON.toJSONString(priceQueryReq), JSON.toJSONString(priceQueryRep));
            createErrorLog("查询价格失败", nykSaleOrder, doHandlerRequest);
            return null;
        }

        return price;
    }


    @NotNull
    private PriceQueryRequest buildPriceRequest(NykSaleOrder nykSaleOrder, AllocateOrderDetail allocateOrderDetail, DoHandlerRequest doHandlerRequest) {

        String customer = null;
        String customerAddress = null;

        try {
            Map<String, Object> nykMainSaleOrder = (Map<String, Object>) nykSaleOrder.getHeader();
            if (nykMainSaleOrder != null && nykMainSaleOrder.get("vbakKunnr") != null && nykMainSaleOrder.get("vbpaKunnrwe") != null) {
                customer = trimForSpecString(String.valueOf(nykMainSaleOrder.get("vbakKunnr")));
                customerAddress = trimForSpecString(String.valueOf(nykMainSaleOrder.get("vbpaKunnrwe")));
            }
        } catch (Exception e) {
            createErrorLog("获取销售订单的客户信息和送达方失败", nykSaleOrder, doHandlerRequest);
            log.error(e, "获取销售订单的客户信息和送达方失败, nykSaleOrder:{}", JSON.toJSONString(nykSaleOrder));
        }

        if (StringUtils.isAnyBlank(customer, customerAddress)) {
            //构建人的信息
            AllocateApplyOrder applyOrder = queryAllocateApplyOrder(nykSaleOrder.getPreorderId());
            if (applyOrder == null) {
                createErrorLog("查询价格失败，没有找到预报单[PreorderId=" + nykSaleOrder.getPreorderId() + "]", nykSaleOrder, doHandlerRequest);
                return null;
            }

            customer = applyOrder.getCustomer();
            customerAddress = applyOrder.getCustomerAddress();
        }

        PriceQueryRequest priceQueryReq = new PriceQueryRequest();
        List<DimensionPropertyInfoRequest> dimensionList = Lists.newArrayList();
        DimensionPropertyInfoRequest request = new DimensionPropertyInfoRequest();

        request.setPriceTypeId(PriceTypeEnum.ZMN1.getCode());
        request.setQueryFlag("nyk");
        request.setPriceUseDate(new Date());

        //构建货品的信息
        MaterialInfoRequest materialInfoRequest = new MaterialInfoRequest();
        materialInfoRequest.setMaterialCode(allocateOrderDetail.getScItemId());
        materialInfoRequest.setScItemGroupCode("11");
        request.setMaterialInfoRequest(materialInfoRequest);

        HumanInfoRequest humanInfoRequest = new HumanInfoRequest();
        humanInfoRequest.setCustomerCode(customer);
        humanInfoRequest.setCustomerSaleAddressCode(customerAddress);
        request.setHumanInfoRequest(humanInfoRequest);

        //构建场的信息
        PlaceInfoRequest placeInfoRequest = new PlaceInfoRequest();
        placeInfoRequest.setOrgSalesOrganizationCode("286072177888956796");
        placeInfoRequest.setSalesUnitCode("PC");
        placeInfoRequest.setChannelCode("20");
        placeInfoRequest.setFactoryCode(nykSaleOrder.getVbapWerks());
        request.setPlaceInfoRequest(placeInfoRequest);

        dimensionList.add(request);
        priceQueryReq.setDimensionPropertyInfoRequestList(dimensionList);

        Map featureMap = Maps.newHashMap();
        featureMap.put("codeFlag", "inner_code_to_out_code");
        priceQueryReq.setFeatures(featureMap);
        return priceQueryReq;
    }

    /**
     * 根据外部单号获取主单信息， 通过销售订单是上的 preorderid 获取预报子单行， 通过预报子单获取预报主单
     *
     * @param preOrderId
     * @return
     */
    private AllocateApplyOrder queryAllocateApplyOrder(String preOrderId) {
        Integer mainApplyOrderId = null;
        Result<List<AllocateApplyOrderDetail>> allocateApplyOrderDetail = loadAllocateApplyOrderDetailByOutId(preOrderId);
        if (allocateApplyOrderDetail != null && org.apache.commons.collections.CollectionUtils.isNotEmpty(allocateApplyOrderDetail.getResult())) {
            // 删除子单
            AllocateApplyOrderDetail applyOrderDetail = allocateApplyOrderDetail.getResult().get(0);
            mainApplyOrderId = applyOrderDetail.getAllocateApplyOrderId();
        }

        if (mainApplyOrderId == null) {
            return null;
        }

        AllocateApplyOrderLoadListRequest request = new AllocateApplyOrderLoadListRequest();
        request.setId(mainApplyOrderId.longValue());
        Result<List<AllocateApplyOrder>> listResult = allocateApplyOrderService.loadAllocateApplyOrderList(request);
        List<AllocateApplyOrder> result = listResult.getResult();
        if (CollectionUtils.isEmpty(result)) {
            return null;
        }
        if (result.size() <= 0) {
            return null;
        }
        return result.get(0);
    }

    private Result<List<AllocateApplyOrderDetail>> loadAllocateApplyOrderDetailByOutId(String outLineNo) {
        AllocateApplyOrderDetailListRequest request = new AllocateApplyOrderDetailListRequest();
        request.setOutLineNo(outLineNo);
        Result<List<AllocateApplyOrderDetail>> allocateApplyOrderDetailResult = allocateApplyOrderDetailService.loadAllocateApplyOrderDetailList2(request);
        return allocateApplyOrderDetailResult;
    }

    private String parseDate(String date) {
        if (StringUtils.isBlank(date)) {
            return null;
        }
        //数据格式不为2021-01-01不处理
        if (date.length() != 10) {
            return null;
        }
        return date + " 00:00:00";
    }

    private String getName(WmsQueryWarehouseZoneListResponse response) {
        if (response != null && CollectionUtils.isNotEmpty(response.getResult())) {
            WarehouseInfo warehouseInfo = response.getResult().get(0);
            return warehouseInfo.getName();
        }
        return null;
    }

    private String getSaleOrgId(WmsQueryWarehouseZoneListResponse response) {
        if (response != null && CollectionUtils.isNotEmpty(response.getResult())) {
            WarehouseInfo warehouseInfo = response.getResult().get(0);
            return warehouseInfo.getSapSaleOrgId();
        }
        return null;
    }

    private String getUnitByOutCode(String outCode) {
        String code = deleteZeroPrefix(outCode);
        if (StringUtils.isNotBlank(code)) {
            BaselineQueryScItemByPageRequest baselineQueryScItemByPageRequest = new BaselineQueryScItemByPageRequest();
            baselineQueryScItemByPageRequest.setOutIdList(Lists.newArrayList(code));
            Object obj = baseDataService.baselineQueryScItemByPage(baselineQueryScItemByPageRequest);
            if (obj != null) {
                JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(obj));
                if (jsonObject != null) {
                    jsonObject = jsonObject.getJSONObject("result");
                    if (jsonObject != null) {
                        jsonObject = jsonObject.getJSONObject("result");
                        if (jsonObject != null) {
                            JSONArray array = jsonObject.getJSONArray("searchResult");
                            if (array != null && array.size() > 0) {
                                jsonObject = array.getJSONObject(0).getJSONObject("features");
                                if (jsonObject != null) {
                                    return jsonObject.getString("unitName");
                                }
                            }
                        }
                    }
                }
            }
        }
        return null;
    }

    private String getItNameByOutCode(String outCode) {
        String code = deleteZeroPrefix(outCode);
        if (StringUtils.isNotBlank(code)) {
            BaselineQueryScItemByPageRequest baselineQueryScItemByPageRequest = new BaselineQueryScItemByPageRequest();
            baselineQueryScItemByPageRequest.setOutIdList(Lists.newArrayList(code));
            Object obj = baseDataService.baselineQueryScItemByPage(baselineQueryScItemByPageRequest);
            if (obj != null) {
                JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(obj));
                if (jsonObject != null) {
                    jsonObject = jsonObject.getJSONObject("result");
                    if (jsonObject != null) {
                        jsonObject = jsonObject.getJSONObject("result");
                        if (jsonObject != null) {
                            JSONArray array = jsonObject.getJSONArray("searchResult");
                            if (array != null && array.size() > 0) {
                                Object title = array.getJSONObject(0).get("title");
                                if (title != null) {
                                    return title.toString();
                                }
                            }
                        }
                    }
                }
            }
        }
        return null;
    }

    public static String deleteZeroPrefix(String str) {
        if (StringUtils.isBlank(str)) {
            return null;
        }
        return str.replaceFirst("^0*", "");
    }

    private String check(NykSaleOrder sdo) {
//        if (Objects.isNull(sdo.getOrderStatus())) {
//            return "orderStatus 不能为空";
//        }
        if (StringUtils.isBlank(sdo.getHeadId())) {
            return "headId 不能为空";
        }
        if (StringUtils.isBlank(sdo.getFromSys())) {
            return "fromSys 不能为空";
        }
        if (StringUtils.isBlank(sdo.getVbapLgort())) {
            return "vbapLgort 不能为空";
        }
        if (StringUtils.isBlank(sdo.getVbapWerks())) {
            return "vbapWerks 不能为空";
        }

        if (StringUtils.isBlank(sdo.getId())) {
            return "id 不能为空";
        }
        if (StringUtils.isBlank(sdo.getVbapMatnr())) {
            return "vbapMatnr 不能为空";
        }
        if (ObjectUtils.isEmpty(sdo.getVbapKwmeng())) {
            return "vbapKwmeng 不能为空";
        }
//        if (ObjectUtils.isEmpty(sdo.getKomvKwert()) && StringUtils.isBlank(sdo.getVbapMatnr())) {
//            return "komvKwert 不能为空";
//        }
        return null;
    }

    //删除主单中已存在的子单，如果子单删光了就把主单也删掉
    private AllocateOrder deleteAllocateOrder(AllocateOrder mainOrder, List<NykSaleOrder> subOrders) {
        if (mainOrder == null || CollectionUtils.isEmpty(subOrders)) {
            return mainOrder;
        }

        // 查询主单的子单列表
        AllocateOrderDetailLoadListRequest request = new AllocateOrderDetailLoadListRequest();
        request.setAllocateOrderId(mainOrder.getId());
        Result<List<AllocateOrderDetail>> detailList = allocateOrderDetailService.loadAllocateOrderDetailList(request);
        Map<String, List<AllocateOrderDetail>> outLineDetailMap = Maps.newHashMap();
        if (detailList != null && CollectionUtils.isNotEmpty(detailList.getResult())) {
            outLineDetailMap = detailList.getResult().stream().collect(Collectors.groupingBy(o->deleteZeroPrefix(o.getOutAllocateOrderLineId())));
        }

        for (NykSaleOrder subOrder : subOrders) {
            String outLineNo = deleteZeroPrefix(subOrder.getVbapPosnr());
            List<AllocateOrderDetail> orderDetails = Optional.ofNullable(outLineDetailMap.get(outLineNo)).orElse(Lists.newArrayList());
            for (AllocateOrderDetail orderDetail : orderDetails) {
                DeleteAllocateOrderDetailRequest req = new DeleteAllocateOrderDetailRequest();
                req.setId(String.valueOf(orderDetail.getId()));
                allocateOrderDetailService.deleteAllocateOrderDetail(req);
            }

            outLineDetailMap.remove(outLineNo);
        }

        if (MapUtils.isEmpty(outLineDetailMap)) {
            DeleteAllocateOrderRequest deleteAllocateOrderRequest = new DeleteAllocateOrderRequest();
            deleteAllocateOrderRequest.setId(String.valueOf(mainOrder.getId()));
            allocateOrderService.deleteAllocateOrder(deleteAllocateOrderRequest);

            return null;
        }

        return mainOrder;

    }

}
